import { exec } from 'child_process';
import { promisify } from 'util';
import os from 'os';
import fs from 'fs';
import path from 'path';

const execAsync = promisify(exec);

export class SystemProxyManager {
  constructor(proxyHost = 'localhost', proxyPort = 12300) {
    this.platform = os.platform();
    this.originalProxySettings = null;
    this.isProxySet = false;
    this.proxyHost = proxyHost;
    this.proxyPort = proxyPort;
    this.backupFile = path.join(process.cwd(), '.proxy-backup.json');
  }

  async setSystemProxy() {
    try {
      console.log('🔧 正在设置系统代理...');
      
      // 先备份当前设置到文件
      await this.backupProxySettingsToFile();
      
      if (this.platform === 'win32') {
        await this.setWindowsProxy();
      } else if (this.platform === 'darwin') {
        await this.setMacOSProxy();
      } else {
        console.warn('⚠️ 当前系统不支持自动代理设置，请手动配置');
        return false;
      }
      
      this.isProxySet = true;
      console.log(`✅ 系统代理已设置: ${this.proxyHost}:${this.proxyPort}`);
      return true;
    } catch (error) {
      console.error('❌ 设置系统代理失败:', error.message);
      // 如果设置失败，尝试恢复原始设置
      await this.restoreSystemProxy();
      return false;
    }
  }

  async restoreSystemProxy() {
    try {
      console.log('🔄 正在恢复系统代理设置...');
      
      // 从文件恢复备份设置
      await this.restoreProxySettingsFromFile();
      
      if (this.platform === 'win32') {
        await this.restoreWindowsProxy();
      } else if (this.platform === 'darwin') {
        await this.restoreMacOSProxy();
      }
      
      this.isProxySet = false;
      console.log('✅ 系统代理设置已恢复');
      
      // 清理备份文件
      this.cleanupBackupFile();
      
      return true;
    } catch (error) {
      console.error('❌ 恢复系统代理失败:', error.message);
      // 如果恢复失败，强制禁用代理
      await this.forceDisableProxy();
      return false;
    }
  }

  async backupProxySettingsToFile() {
    try {
      if (this.platform === 'win32') {
        await this.backupWindowsProxySettings();
      } else if (this.platform === 'darwin') {
        await this.backupMacOSProxySettings();
      }
      
      // 将备份保存到文件
      if (this.originalProxySettings) {
        fs.writeFileSync(this.backupFile, JSON.stringify(this.originalProxySettings, null, 2));
        console.log('📋 代理设置已备份到文件');
      }
    } catch (error) {
      console.warn('⚠️ 备份代理设置到文件失败:', error.message);
    }
  }

  async restoreProxySettingsFromFile() {
    try {
      if (fs.existsSync(this.backupFile)) {
        const backupData = fs.readFileSync(this.backupFile, 'utf8');
        this.originalProxySettings = JSON.parse(backupData);
        console.log('📋 从文件恢复代理设置备份');
      }
    } catch (error) {
      console.warn('⚠️ 从文件恢复代理设置失败:', error.message);
    }
  }

  cleanupBackupFile() {
    try {
      if (fs.existsSync(this.backupFile)) {
        fs.unlinkSync(this.backupFile);
        console.log('🧹 已清理代理备份文件');
      }
    } catch (error) {
      console.warn('⚠️ 清理备份文件失败:', error.message);
    }
  }

  async forceDisableProxy() {
    try {
      console.log('🚨 强制禁用系统代理...');
      
      if (this.platform === 'win32') {
        // 强制禁用Windows代理
        await execAsync(`reg add "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings" /v ProxyEnable /t REG_DWORD /d 0 /f`);
        await this.refreshWindowsProxy();
        console.log('✅ 已强制禁用Windows代理');
      } else if (this.platform === 'darwin') {
        // 强制禁用macOS代理
        const { stdout } = await execAsync('networksetup -listallnetworkservices');
        const services = stdout.split('\n')
          .filter(line => line.trim() && !line.startsWith('*'))
          .slice(1);

        for (const service of services) {
          const serviceName = service.trim();
          if (!serviceName) continue;
          
          try {
            await execAsync(`networksetup -setwebproxystate "${serviceName}" off`);
            await execAsync(`networksetup -setsecurewebproxystate "${serviceName}" off`);
          } catch (error) {
            // 忽略单个服务的错误
          }
        }
        console.log('✅ 已强制禁用macOS代理');
      }
    } catch (error) {
      console.error('❌ 强制禁用代理失败:', error.message);
    }
  }

  async setWindowsProxy() {
    // 设置代理
    const commands = [
      // 启用代理
      `reg add "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings" /v ProxyEnable /t REG_DWORD /d 1 /f`,
      // 设置代理服务器
      `reg add "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings" /v ProxyServer /t REG_SZ /d "${this.proxyHost}:${this.proxyPort}" /f`,
      // 设置代理覆盖（不代理本地地址）
      `reg add "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings" /v ProxyOverride /t REG_SZ /d "localhost;localhost:*;127.*;127.0.0.1:*;*.localhost;::1;10.*;172.16.*;172.17.*;172.18.*;172.19.*;172.20.*;172.21.*;172.22.*;172.23.*;172.24.*;172.25.*;172.26.*;172.27.*;172.28.*;172.29.*;172.30.*;172.31.*;192.168.*;<local>" /f`
    ];

    for (const command of commands) {
      // 为每个命令设置10秒超时
      const timeoutPromise = new Promise((_, reject) => {
        setTimeout(() => reject(new Error(`注册表命令超时: ${command}`)), 10000);
      });
      
      await Promise.race([execAsync(command), timeoutPromise]);
    }

    // 刷新代理设置（带超时）
    await this.refreshWindowsProxy();
  }

  async restoreWindowsProxy() {
    if (this.originalProxySettings) {
      const { proxyEnable, proxyServer, proxyOverride } = this.originalProxySettings;
      
      const commands = [
        `reg add "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings" /v ProxyEnable /t REG_DWORD /d ${proxyEnable || 0} /f`
      ];
      
      if (proxyServer) {
        commands.push(`reg add "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings" /v ProxyServer /t REG_SZ /d "${proxyServer}" /f`);
      } else {
        commands.push(`reg delete "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings" /v ProxyServer /f 2>nul || echo "ProxyServer key not found"`);
      }
      
      if (proxyOverride) {
        commands.push(`reg add "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings" /v ProxyOverride /t REG_SZ /d "${proxyOverride}" /f`);
      } else {
        commands.push(`reg delete "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings" /v ProxyOverride /f 2>nul || echo "ProxyOverride key not found"`);
      }

      for (const command of commands) {
        try {
          await execAsync(command);
        } catch (error) {
          console.warn('⚠️ 执行注册表命令失败:', command, error.message);
        }
      }
    } else {
      // 如果没有备份，则直接禁用代理
      console.log('⚠️ 没有找到原始代理设置，将禁用代理');
      await execAsync(`reg add "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings" /v ProxyEnable /t REG_DWORD /d 0 /f`);
    }

    // 刷新代理设置
    await this.refreshWindowsProxy();
  }

  async backupWindowsProxySettings() {
    try {
      // 读取当前代理设置
      const proxyEnableResult = await execAsync(`reg query "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings" /v ProxyEnable 2>nul`);
      const proxyServerResult = await execAsync(`reg query "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings" /v ProxyServer 2>nul`).catch(() => ({ stdout: '' }));
      const proxyOverrideResult = await execAsync(`reg query "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings" /v ProxyOverride 2>nul`).catch(() => ({ stdout: '' }));

      // 解析代理启用状态
      const proxyEnableMatch = proxyEnableResult.stdout.match(/ProxyEnable\s+REG_DWORD\s+0x(\d+)/);
      const proxyEnable = proxyEnableMatch ? parseInt(proxyEnableMatch[1], 16) : 0;

      // 解析代理服务器
      const proxyServerMatch = proxyServerResult.stdout.match(/ProxyServer\s+REG_SZ\s+(.+)/);
      const proxyServer = proxyServerMatch ? proxyServerMatch[1].trim() : null;

      // 解析代理覆盖
      const proxyOverrideMatch = proxyOverrideResult.stdout.match(/ProxyOverride\s+REG_SZ\s+(.+)/);
      const proxyOverride = proxyOverrideMatch ? proxyOverrideMatch[1].trim() : null;

      this.originalProxySettings = {
        proxyEnable,
        proxyServer,
        proxyOverride
      };

      console.log('📋 已备份Windows代理设置:', this.originalProxySettings);
    } catch (error) {
      console.warn('⚠️ 备份Windows代理设置失败:', error.message);
      this.originalProxySettings = { proxyEnable: 0, proxyServer: null, proxyOverride: null };
    }
  }

  async refreshWindowsProxy() {
    try {
      // 刷新Internet Explorer设置（影响系统代理）
      await execAsync('rundll32.exe wininet.dll,InternetSetOption 39,0,0,0');
      await execAsync('rundll32.exe wininet.dll,InternetSetOption 37,0,0,0');
      console.log('🔄 已刷新Windows代理设置');
    } catch (error) {
      console.warn('⚠️ 刷新Windows代理设置失败:', error.message);
    }
  }

  async backupMacOSProxySettings() {
    try {
      // 获取所有网络服务
      const { stdout } = await execAsync('networksetup -listallnetworkservices');
      const services = stdout.split('\n')
        .filter(line => line.trim() && !line.startsWith('*'))
        .slice(1);

      const backupSettings = {};

      for (const service of services) {
        const serviceName = service.trim();
        if (!serviceName) continue;

        try {
          // 获取HTTP代理设置
          const httpProxyResult = await execAsync(`networksetup -getwebproxy "${serviceName}"`);
          const httpsProxyResult = await execAsync(`networksetup -getsecurewebproxy "${serviceName}"`);

          backupSettings[serviceName] = {
            http: this.parseMacOSProxyOutput(httpProxyResult.stdout),
            https: this.parseMacOSProxyOutput(httpsProxyResult.stdout)
          };
        } catch (error) {
          console.warn(`⚠️ 备份服务 ${serviceName} 的代理设置失败:`, error.message);
        }
      }

      this.originalProxySettings = { services: backupSettings };
      console.log('📋 已备份macOS代理设置');
    } catch (error) {
      console.warn('⚠️ 备份macOS代理设置失败:', error.message);
      this.originalProxySettings = { services: {} };
    }
  }

  async setMacOSProxy() {
    try {
      // 获取所有网络服务
      const { stdout } = await execAsync('networksetup -listallnetworkservices');
      const services = stdout.split('\n')
        .filter(line => line.trim() && !line.startsWith('*'))
        .slice(1);

      for (const service of services) {
        const serviceName = service.trim();
        if (!serviceName) continue;

        try {
          // 设置HTTP代理
          await execAsync(`networksetup -setwebproxy "${serviceName}" ${this.proxyHost} ${this.proxyPort}`);
          // 设置HTTPS代理
          await execAsync(`networksetup -setsecurewebproxy "${serviceName}" ${this.proxyHost} ${this.proxyPort}`);
        } catch (error) {
          console.warn(`⚠️ 为服务 ${serviceName} 设置代理失败:`, error.message);
        }
      }

      console.log('✅ 已设置macOS系统代理');
    } catch (error) {
      console.error('❌ 设置macOS代理失败:', error.message);
      throw error;
    }
  }

  async restoreMacOSProxy() {
    if (!this.originalProxySettings?.services) {
      console.log('⚠️ 没有找到原始macOS代理设置，将禁用所有代理');
      await this.forceDisableProxy();
      return;
    }

    try {
      for (const [serviceName, settings] of Object.entries(this.originalProxySettings.services)) {
        try {
          // 恢复HTTP代理
          if (settings.http.enabled) {
            await execAsync(`networksetup -setwebproxy "${serviceName}" ${settings.http.server} ${settings.http.port}`);
          } else {
            await execAsync(`networksetup -setwebproxystate "${serviceName}" off`);
          }

          // 恢复HTTPS代理
          if (settings.https.enabled) {
            await execAsync(`networksetup -setsecurewebproxy "${serviceName}" ${settings.https.server} ${settings.https.port}`);
          } else {
            await execAsync(`networksetup -setsecurewebproxystate "${serviceName}" off`);
          }
        } catch (error) {
          console.warn(`⚠️ 恢复服务 ${serviceName} 的代理设置失败:`, error.message);
        }
      }

      console.log('✅ 已恢复macOS代理设置');
    } catch (error) {
      console.error('❌ 恢复macOS代理失败:', error.message);
      throw error;
    }
  }

  parseMacOSProxyOutput(output) {
    const lines = output.split('\n');
    const result = { enabled: false, server: null, port: null };

    for (const line of lines) {
      if (line.includes('Enabled: Yes')) {
        result.enabled = true;
      } else if (line.includes('Server:')) {
        result.server = line.split('Server:')[1]?.trim();
      } else if (line.includes('Port:')) {
        result.port = line.split('Port:')[1]?.trim();
      }
    }

    return result;
  }

  async getProxyStatus() {
    try {
      if (this.platform === 'win32') {
        const result = await execAsync(`reg query "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings" /v ProxyEnable 2>nul`);
        const match = result.stdout.match(/ProxyEnable\s+REG_DWORD\s+0x(\d+)/);
        const enabled = match ? parseInt(match[1], 16) === 1 : false;

        if (enabled) {
          const serverResult = await execAsync(`reg query "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings" /v ProxyServer 2>nul`).catch(() => ({ stdout: '' }));
          const serverMatch = serverResult.stdout.match(/ProxyServer\s+REG_SZ\s+(.+)/);
          const server = serverMatch ? serverMatch[1].trim() : null;

          return {
            enabled,
            server,
            isOurs: server === `${this.proxyHost}:${this.proxyPort}`
          };
        }

        return { enabled: false, server: null, isOurs: false };
      } else if (this.platform === 'darwin') {
        // macOS代理状态检查较复杂，这里简化处理
        return { enabled: this.isProxySet, server: `${this.proxyHost}:${this.proxyPort}`, isOurs: this.isProxySet };
      }

      return { enabled: false, server: null, isOurs: false };
    } catch (error) {
      console.warn('⚠️ 获取代理状态失败:', error.message);
      return { enabled: false, server: null, isOurs: false };
    }
  }

  async emergencyRestore() {
    console.log('🚨 执行应急恢复...');
    
    try {
      console.log('🔍 检查当前代理状态...');
      const status = await this.getProxyStatus();
      
      if (status.enabled) {
        console.log(`📡 当前代理状态: ${status.enabled ? "已启用" : "已禁用"}`);
        if (status.server) {
          console.log(`🌐 代理服务器: ${status.server}`);
          console.log(`🎯 是否为我们的代理: ${status.isOurs ? "是" : "否"}`);
        }
      } else {
        console.log('✅ 当前系统代理已禁用，无需恢复');
        return true;
      }
      
      console.log('🔄 开始恢复代理设置...');
      
      // 尝试从备份文件恢复
      await this.restoreProxySettingsFromFile();
      
      // 执行恢复
      const success = await this.restoreSystemProxy();
      
      if (success) {
        console.log('✅ 应急恢复完成！');
        console.log('🌐 您的网络连接应该已经恢复正常');
        
        // 再次检查状态
        const newStatus = await this.getProxyStatus();
        console.log(`📊 恢复后状态: ${newStatus.enabled ? "代理已启用" : "代理已禁用"}`);
        
        return true;
      } else {
        throw new Error('恢复操作失败');
      }
      
    } catch (error) {
      console.error('❌ 应急恢复失败:', error.message);
      console.log('🔄 尝试强制禁用代理...');
      
      try {
        await this.forceDisableProxy();
        console.log('✅ 强制禁用代理成功');
        return true;
      } catch (forceError) {
        console.error('❌ 强制禁用代理也失败:', forceError.message);
        this.printManualRestoreGuide();
        return false;
      }
    }
  }

  printManualRestoreGuide() {
    console.log('\n🔧 手动恢复指南:');
    console.log('Windows用户:');
    console.log('1. 打开"设置" > "网络和Internet" > "代理"');
    console.log('2. 关闭"使用代理服务器"选项');
    console.log('3. 或运行命令: reg add "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings" /v ProxyEnable /t REG_DWORD /d 0 /f');
    
    console.log('\nmacOS用户:');
    console.log('1. 打开"系统偏好设置" > "网络"');
    console.log('2. 选择您的网络连接，点击"高级"');
    console.log('3. 在"代理"标签页中，取消选中所有代理选项');
  }

  getStatus() {
    return {
      isProxySet: this.isProxySet,
      proxyHost: this.proxyHost,
      proxyPort: this.proxyPort,
      platform: this.platform,
      hasBackup: !!this.originalProxySettings,
      backupFileExists: fs.existsSync(this.backupFile)
    };
  }
} 